# 编译器警告配置模块
# 为不同编译器设置合适的警告标志

function(set_project_warnings project_name)
    option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" FALSE)

    set(MSVC_WARNINGS
        /W4     # 合理且可达到的最高级别警告
        /w14242 # 可能的精度损失
        /w14254 # 运算符重载可能的精度损失
        /w14263 # 成员函数不覆盖任何基类虚函数
        /w14265 # 类有虚函数但析构函数不是虚的
        /w14287 # 未签名/有符号不匹配
        /we4289 # 非标准扩展使用：循环控制变量在for循环外声明
        /w14296 # 表达式总是false
        /w14311 # 指针截断
        /w14545 # 函数调用前的表达式计算为函数
        /w14546 # 函数调用缺少参数列表
        /w14547 # 运算符前的表达式无效果
        /w14549 # 运算符前的表达式可能有副作用
        /w14555 # 表达式无效果
        /w14619 # pragma warning中没有警告编号
        /w14640 # 非线程安全的静态成员初始化
        /w14826 # 从指针类型转换是符号扩展的
        /w14905 # 宽字符串字面量转换为LPSTR
        /w14906 # 字符串字面量转换为LPWSTR
        /w14928 # 非法复制初始化
    )

    set(CLANG_WARNINGS
        -Wall
        -Wextra
        -Wshadow
        -Wnon-virtual-dtor
        -Wold-style-cast
        -Wcast-align
        -Wunused
        -Woverloaded-virtual
        -Wpedantic
        -Wconversion
        -Wsign-conversion
        -Wnull-dereference
        -Wdouble-promotion
        -Wformat=2
    )

    if(WARNINGS_AS_ERRORS)
        set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror)
        set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX)
    endif()

    set(GCC_WARNINGS
        ${CLANG_WARNINGS}
        -Wmisleading-indentation
        -Wduplicated-cond
        -Wduplicated-branches
        -Wlogical-op
        -Wuseless-cast
    )

    if(MSVC)
        set(PROJECT_WARNINGS ${MSVC_WARNINGS})
    elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
        set(PROJECT_WARNINGS ${CLANG_WARNINGS})
    elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
        set(PROJECT_WARNINGS ${GCC_WARNINGS})
    else()
        message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
    endif()

    target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS})
endfunction() 